package com.app.system.exception;

import com.app.system.log4j2.LogUtils;
import com.app.system.utils.exception.AjaxException;
import com.app.system.utils.exception.RequestLimitException;
import com.app.system.utils.exception.Response;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by wcf-pc on 2018/4/17.
 *
 * @author wcf-pc
 */
@ControllerAdvice
@SuppressWarnings("all")
public class GlobalExceptionHandler {

    private static final Logger logger = LogUtils.getExceptionLogger();

    public static final String DEFAULT_ERROR_VIEW = "/error/error";//错误提示页面
    public static final String NO_PERMISSION_VIEW = "/error/unauthorizeUrl";//没有权限访问页面

    /**
     * shiro权限不足异常捕获
     * 根据请求返回json或view格式
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = UnauthorizedException.class)//处理访问方法时权限不足问题
    public ModelAndView unauthorizedErrorHandler(HttpServletRequest req, Exception e) {
        //判断是否为ajax请求，默认不是
        boolean isAjaxRequest = false;
        String requestHeader = "x-requested-with", requestXmlHttp = "XMLHttpRequest";
        if (!StringUtils.isEmpty(req.getHeader(requestHeader)) && requestXmlHttp.equals(req.getHeader("x-requested-with"))) {
            isAjaxRequest = true;
        }
        if (isAjaxRequest) {
//            throw new AjaxException("403", "没有访问权限");
            Response response = new Response("403", "访问限制异常");
            MappingJackson2JsonView view = new MappingJackson2JsonView();
            ModelAndView mav = new ModelAndView();
            mav.addObject("code", response.getCode());
            mav.addObject("message", response.getMessage());
            mav.setView(view);

            logger.error(e.getMessage());

            return mav;
        } else {
            ModelAndView mav = new ModelAndView();
            mav.addObject("message", "访问限制异常");
            mav.addObject("exception", e);
            mav.addObject("url", req.getRequestURL());
            mav.setViewName(NO_PERMISSION_VIEW);

            logger.error(e.getMessage());

            return mav;
        }
    }

    /**
     * 秒刷新异常捕获
     * 根据请求返回json或view格式
     *
     * @param req
     * @param e
     * @return
     */
    @ExceptionHandler(value = RequestLimitException.class)//处理访问方法时权限不足问题
    public ModelAndView requestLimitErrorHandler(HttpServletRequest req, Exception e) {
        //判断是否为ajax请求，默认不是
        boolean isAjaxRequest = false;
        String requestHeader = "x-requested-with", requestXmlHttp = "XMLHttpRequest";
        if (!StringUtils.isEmpty(req.getHeader(requestHeader)) && requestXmlHttp.equals(req.getHeader("x-requested-with"))) {
            isAjaxRequest = true;
        }
        if (isAjaxRequest) {
//            throw new AjaxException("403", "没有访问权限");
            Response response = new Response("403", "没有访问权限");
            MappingJackson2JsonView view = new MappingJackson2JsonView();
            ModelAndView mav = new ModelAndView();
            mav.addObject("code", response.getCode());
            mav.addObject("message", response.getMessage());
            mav.setView(view);

            logger.error(e.getMessage());

            return mav;
        } else {
            ModelAndView mav = new ModelAndView();
            mav.addObject("message", "没有访问权限");
            mav.addObject("exception", e);
            mav.addObject("url", req.getRequestURL());
            mav.setViewName(DEFAULT_ERROR_VIEW);

            logger.error(e.getMessage());

            return mav;
        }
    }

    /**
     * ajax方式异常数据友好提示
     *
     * @param req
     * @param e
     * @return
     * @throws Exception
     */
    @ExceptionHandler(value = AjaxException.class)
    @ResponseBody
    public Response<String> ajaxErrorHandler(HttpServletRequest req, AjaxException e) throws Exception {
        Response response = new Response();
        response.setMessage(e.getMessage());
        response.setCode(e.getCode());

        logger.error(e.getMessage());

        return response;
    }

    /**
     * 系统异常捕获
     * 根据请求返回json或view格式
     *
     * @param req
     * @param e
     * @return
     * @throws Exception
     */
//    @ExceptionHandler(value = Exception.class)
    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        //判断是否为ajax请求，默认不是
        boolean isAjaxRequest = false;
        if (!StringUtils.isEmpty(req.getHeader("x-requested-with")) && "XMLHttpRequest".equals(req.getHeader("x-requested-with"))) {
            isAjaxRequest = true;
        }
        if (isAjaxRequest) {
            Response response = new Response("500", "系统错误提示");
            MappingJackson2JsonView view = new MappingJackson2JsonView();
            ModelAndView mav = new ModelAndView();
            mav.addObject("code", response.getCode());
            mav.addObject("message", response.getMessage());
            mav.addObject("exception", e);
            mav.addObject("url", req.getRequestURL());
            mav.setView(view);

            logger.error(e.getMessage());

            return mav;
        } else {
            ModelAndView mav = new ModelAndView();
            mav.addObject("code", "500");
            mav.addObject("message", "系统错误提示");
            mav.addObject("exception", e);
            mav.addObject("url", req.getRequestURL());
            mav.setViewName(DEFAULT_ERROR_VIEW);

            logger.error(e.getMessage());

            return mav;
        }
    }


}
